/**
 * 案例：
 *    1. 实现一个前端搜索功能
 */

// 引入拆分出去的组件
import TaskSearch from "./components/TaskSearch";
import TaskList from "./components/TaskList";
import TaskAdd from "./components/TaskAdd";
import { nanoid } from "nanoid";
import { useMemo, useState } from "react";

function App() {
  // 搜索关键字
  const [keyword, setKeyword] = useState("");
  // 待办事项列表数据
  const [tasks, setTasks] = useState([
    { id: 1, title: "吃饭", done: false },
    { id: 2, title: "睡觉", done: false },
    { id: 3, title: "打豆豆", done: true },
  ]);

  // 搜索结果数据，
  const searchResult = useMemo(() => {
    if (!keyword) {
      // 返回全量数据
      return [...tasks];
    }
    // 精准搜索
    // return tasks.filter((item) => item.title === keyword);

    // 模糊搜索
    return tasks.filter((item) => item.title.includes(keyword));
  }, [tasks, keyword]);

  // 是否全选
  const isCheckedAll = useMemo(() => {
    // 勾选了的数据长度，是否等于源数组的长度
    if (!tasks.length) return false;

    return tasks.filter((item) => item.done).length === tasks.length;
  }, [tasks]);

  /**
   * // 搜索方法
   * @param {*} title 搜索关键字
   */
  function onSearch(title) {
    // 将 title 赋值给 keyword
    setKeyword(title);

    // 根据 这个 title 与 tasks 做一个过滤，过滤出 tasks 中 title 字段与 这里的 title 参数一样的内容
    // console.log("onSearch title", title);
    // const result = tasks.filter((item) => item.title === title);
    // console.log("onSearch result", result);
    // 将 result 作为 TaskList 组件的 list prop
    //    思考，我能直接将 result 赋值给 tasks 嘛？ 不可以，修改掉源数据之后，会让我们数据无法回退
    //        setTasks(result);
    //        应该再设置一个数据，是基于 搜素关键字与tasks算出来的一份搜索结果数据。使用 useMemo
  }

  /**
   * 处理勾选操作
   * @param {*} id 需要操作的task的Id
   * @param {*} checked 是否勾选
   */
  function onChange(id, checked) {
    setTasks((prevTasks) => {
      return prevTasks.map((item) => {
        if (item.id === id) {
          return {
            ...item,
            done: checked,
          };
        } else {
          return item;
        }
      });
    });
  }

  /**
   * 处理 title 修改
   * @param {*} id 需要操作的 task 的 id
   * @param {*} title 新的 title 的值
   */
  function onChangeTitle(id, title) {
    setTasks((tasks) =>
      tasks.map((item) => {
        if (item.id === id) {
          return {
            ...item,
            title: title,
          };
        } else {
          return item;
        }
      })
    );
  }

  /**
   * 处理全选与反选操作
   * @param {*} checked 是否要全选
   */
  function onChangeAll(checked) {
    if (checked) {
      // 全选，将 tasks 中所有数据的 done 设置为 true
      setTasks((prevTasks) =>
        prevTasks.map((item) => ({ ...item, done: true }))
      );
    } else {
      // 反选，将 tasks 中所有数据的 done 设置为 false
      setTasks((prevTasks) =>
        prevTasks.map((item) => ({ ...item, done: false }))
      );
    }
  }

  /**
   * 删除某一项 task
   * @param {*} id task的 Id
   */
  function onDelete(id) {
    setTasks((prevTasks) => prevTasks.filter((item) => item.id !== id));
  }

  /**
   * 添加一个待办事项
   * @param {*} title 标题
   */
  function onAdd(title) {
    setTasks((tasks) => [
      ...tasks,
      {
        // id 使用当前数组长度 + 1 的方式，会有些问题，
        // 需要处理的话，可以用一个 nanoid 的 npm 包
        // id: tasks.length + 1,
        id: nanoid(),
        title: title,
        done: false,
      },
    ]);
  }

  return (
    <div>
      {/* <button onClick={() => onAdd("游戏")}>添加</button> */}
      <h1>App</h1>
      <TaskAdd onAdd={onAdd} />
      <hr />
      <TaskSearch keyword={keyword} onSearch={onSearch} />
      <hr />
      <TaskList
        list={searchResult}
        isCheckedAll={isCheckedAll}
        onDelete={onDelete}
        onChange={onChange}
        onChangeAll={onChangeAll}
        onChangeTitle={onChangeTitle}
      />
    </div>
  );
}

export default App;
